package com.shiro.web.realm;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.shiro.web.model.User;
import com.shiro.web.service.PermService;
import com.shiro.web.service.RoleService;
import com.shiro.web.service.UserService;

public class ShiroRealm extends AuthorizingRealm {

	@Autowired
	private UserService userService;
	
	@Autowired
	private RoleService roleService;
	
	@Autowired
	private PermService permService;
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		if(principals == null){
			throw new AuthorizationException("principals should not be null");
		}
		String username =(String) principals.fromRealm(this.getName()).iterator().next();
		User user = userService.findUserByName(username);
		// ROLE
		List<String> roleCodes = roleService.query(user);
		if(roleCodes.size() == 0) return null;
		Set<String> roles = new HashSet<String>();
		for (String string : roleCodes) {
			Logger.getLogger(this.getClass()).info("[ROLE] - " + string);
			roles.add(string);
		}
		// Permissions
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles);
		List<String> perms = permService.getPermissions(roleCodes);
		Set<String> permis = new HashSet<String>();
		for (String string : perms) {
			permis.add(string);
			Logger.getLogger(this.getClass()).info("[PERMIS] - " + string);
		}
		info.setStringPermissions(permis);
		return info;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authenToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authenToken;
		String username = token.getUsername();
		User user = userService.findUserByName(username);
		
		if (user == null) {
			throw new UnknownAccountException("没有找到相关用户");
		}
		if (user.getPassword().equals(new String(token.getPassword()))){
			return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), this.getName());
		} else {
			throw new AuthenticationException("认证失败");
		}
	}

}
